package vip.yyzhu.redisadmin.api.key.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.Tuple;
import vip.yyzhu.redisadmin.aop.verifyKeyType.VerifyKeyType;
import vip.yyzhu.redisadmin.api.pub.jopo.RedisZset;
import vip.yyzhu.redisadmin.jopo.ResData;
import vip.yyzhu.redisadmin.jopo.ResJson;
import vip.yyzhu.redisadmin.redis.RedisList;
import vip.yyzhu.redisadmin.util.Tool;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/api/key/zset", produces = "application/json;charset=UTF-8")
@SuppressWarnings("all")
public class ZsetController {
    @Autowired
    RedisList redisList;
    @Autowired
    Tool tool;
    ObjectMapper mapper = new ObjectMapper();

    /**
     * 使用游标获取kes列表
     *
     * @param key    zset的key
     * @param cursor 游标
     * @param size   一页的数量
     * @param match  模糊搜索
     * @return {"map":{"total":10, "sift":5, "cursor":"0"}, "list":[]}
     */
    @VerifyKeyType("zset")
    @RequestMapping(value = "/zscan", method = RequestMethod.POST)
    public Object zscan(HttpServletRequest request,
                        @RequestParam String key,
                        @RequestParam String cursor,
                        @RequestParam(required = false, defaultValue = "100") int size,
                        @RequestParam(required = false, defaultValue = "100") int page_size,
                        @RequestParam(required = false) String match) {
        val jedis = tool.getJedis(request);

        ScanParams scanParams = new ScanParams();
        scanParams.count(page_size < 200 ? 200 : page_size);//页数
        if (match != null && !match.equals("")) {
            scanParams.match(match);
        }

        String new_cursor = cursor;
        List<Tuple> list = new ArrayList();
        //  加载到size的数量
        while (list.size() < size) {
            ScanResult<Tuple> scan = jedis.zscan(key, new_cursor, scanParams);
            new_cursor = scan.getStringCursor();
            list.addAll(scan.getResult());
            if (new_cursor.equals("0")) {
                break;
            }
        }
        Map map = new HashMap();
        map.put("total", jedis.zcard(key));
        map.put("cursor", new_cursor);
        ResData res = new ResData();
        res.setList(list);
        res.setMap(map);
        return new ResJson(200, "成功", res);
    }

    /**
     * 删除set指定key
     *
     * @param key    zset的key
     * @param member 要删除的member
     * @return {"redis":"", "map":{"key":a, "member":v}}
     */
    @VerifyKeyType("zset")
    @RequestMapping(value = "/zrem", method = RequestMethod.POST)
    public Object zrem(HttpServletRequest request,
                       @RequestParam String key,
                       @RequestParam String member) throws Exception {
        val jedis = tool.getJedis(request);

        Long srem = jedis.zrem(key, member);
        Map map = new HashMap();
        map.put("key", key);
        map.put("value", member);
        ResData res = new ResData(map);
        res.setRedis(srem);
        return new ResJson(200, "成功", res);
    }


    /**
     * 添加
     *
     * @param key
     * @param cover 是否覆盖添加，默认覆盖
     * @param adds  [{"score":0, "member",""}]
     * @return
     */
    @VerifyKeyType(value = "zset", empty = true)
    @RequestMapping(value = "/zadd", method = RequestMethod.POST)
    public Object zadd(HttpServletRequest request,
                       @RequestParam String key,
                       @RequestParam(required = false, defaultValue = "true") boolean cover,
                       @RequestParam String adds) throws Exception {
        val jedis = tool.getJedis(request);
        // json转liat
        List<RedisZset> list = mapper.readValue(adds, new TypeReference<List<RedisZset>>() {
        });
        // 需要添加的map
        Map<String, Double> success = new HashMap();
        // 已经存在的
        Map<String, Double> repeat = new HashMap();
        for (RedisZset zset : list) {
            if (cover || jedis.zrank(key, zset.getMember()) == null) { // 开启覆盖 或者 key不存在
                success.put(zset.getMember(), zset.getScore());
            } else { // 跳过已存在的
                repeat.put(zset.getMember(), zset.getScore());
            }
        }
        if (success.size() > 0) { // 需要添加的数量不为0
            jedis.zadd(key, success);
        }

        Map map = new HashMap();
        map.put("key", key);
        map.put("repeat", repeat);
        map.put("success", success);
        ResData res = new ResData(map);
        return new ResJson(200, "成功", res);
    }
}
